/***************************************************************************
 *   Copyright (C) 2007 by Ziman & Xloverin                                *
 *   ziman@centrum.sk, xloverin@gmail.com                                  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef TERMINAL_H
#define TERMINAL_H

#include <QWidget>
#include <QString>
#include <QTabWidget>
#include <QTextCursor>
#include "ui_terminal.h"

class Query;

/**
 * Implementuje terminal - vstupny riadok a displej.
 */
class Terminal : public QWidget, private Ui::Terminal
{
	/// Historia vstupneho riadka.
	QStringList inputHistory;

	/// Pozicia v historii.
	int historyPos;

	/// Vravi, ci terminal ma byt farebny.
	bool m_color;

	/// Vravi, ci terminal sa ma uz naozaj zavriet. @see Terminal#closeEvent
	bool m_reallyClose;
	
	/// Font nastaveny v terminali (rez).
	QString m_fontFace;
	
	/// Velkost fontu v terminali.
	int m_fontSize;

	Query *m_query;

	/// Widget, ku ktoremu sa ma attachovat naspat, ak treba.
	QTabWidget *reattachWidget;

	Q_OBJECT

public:

	/// Format vystupu.
	enum Output {
		/// Cisty text zbaveny farebnych kodov.
		PlainText,
  		/// HTML zbavene farebnych kodov.
  		MonoHtml,
		/// HTML s farebnymi kodmi.
		Html
	};

	Terminal();
	virtual ~Terminal();

	/**
	 * Prevedie retazec z VT100 kodovania do HTML a vyeskejpuje specialne znaky.
	 * Zaroven prevedie interpretaciu telnet prikazov (echo on/off).
	 * @param data Text vo VT100 kodovani.
	 * @param stripColor Vravi, ci sa maju z textu odstranit farebne kody.
	 * @param terminal Ak je neNULLovy, tak sa mu nastavi echo podla zadaneho retazca.
	 * @param cursor Ak je neNULLovy, tak sa zan vypise sformatovany text a vrati sa prazdny retazec.
	 * @return HTML/plaintext sformatovany podla parametra output; ak je cursor neNULLovy, vrati sa
	 * 	prazdny retazec.
	 * @see http://www.termsys.demon.co.uk/vtansi.htm
	 */
	static QString interpretVt100(QByteArray data, Output output = Html, Terminal *terminal = 0, QTextCursor *cursor = 0);

	/// Vrati CSS dokument, ktory definuje formatovanie pouzite v Terminal#interpretVt100().
	QString css();

	/// Farebnost terminalu.
	bool color();

	/// Detachne terminal a nastavi mu zadany nadpis.
	void detach(QString title, QTabWidget *reattachTo);

	/// Attachne sa nazad do okna.
	void reattach();

	/// Zavrie terminal.
	void closeTerminal();

	/// Hodi sa napriklad pri mainTerminali.
	void setClosableFromContextMenu(bool closable);

	/// Nastavi terminalu font.
	void setFont(QString face, int size);

	Query *query();
	void setQuery(Query *query);
	
	/// Vrati, ci je echo nastavene.
	bool getEcho() const;

public slots:
	/**
	 * Vypise zadany text vo VT100 kodovani na display. Vsetko sa osetri
	 * (HTML entity, prevod farieb na validne HTML).
	 * @param text Zadany text.
	 * @param stripTelnet Vravi, ci sa maju odstranit z textu vsetky telnetove kody.
	 */
	virtual void write(QByteArray text, bool stripTelnet = true);

	/// Zmaze cely displej.
	virtual void clear();

	/// Nastavi lokalne echo.
	virtual void echo(bool on);

	/// Fokusuje vstupny riadok.
	virtual void focusInput();

	/// Nastavi farebnost terminalu.
	void setColor(bool color);

signals:
	/// Emituje sa, ked user potvrdi enterom zadany riadok.
	void lineSubmitted(QString line);

	/// Tab sa ma zatvorit.
	void closeTab(Terminal *terminal);

	/// Tab sa ma odpojit.
	void detachTab();
	
	/// Tab bol pripojeny.
	void attached();

protected:
	virtual void contextMenuEvent(QContextMenuEvent *evt);
	virtual void closeEvent(QCloseEvent *evt);

protected slots:
	virtual void on_input_returnPressed();
	virtual void on_input_keyPressed(Qt::Key key);
	virtual void on_input_textEdited(const QString &text);

	void on_actionReattach_triggered();
	void on_actionSave_as_HTML_triggered();
	void on_actionClose_triggered();
	void on_actionClear_triggered();
	void on_display_selectionChanged();
};

/// Odstrani diakritiku zo zadaneho retazca.
void stripDiacritics(QString &s);

#endif

